from __future__ import division
import random
import math
import os
from sets import Set

# Updated by Wei 20130525
# some raw results produced by the irtk

# Program inputs:
# gold standard file
# inputFileName1 = ""

# compared file
# inputFileName2 = ""

# Program outputs:
# the symmetric_difference
def getQueryIDAndResultSetGivenResultFile(inputFileName1,numOfLinesStillNeededToSkip):
    numOfQueriesHavingQID = 0
    numOfQueriesHavingSearchContent = 0
    numOfQueriesHavingSearchResults = 0
    
    # key:queryID value:a list of tuples with the format (rank,docID)
    insideQueryIDAndResultSetDict = {}
    
    inputFileHandler1 = open(inputFileName1,"r")
    
    
    
    currentLine = inputFileHandler1.readline()
    nextLine = ""
    currentQID = ""
    
    numOfResultsForTheAllQueries = 0
    
    while currentLine:
        # sampling parsing line:
        # qid: 701
        if currentLine.startswith("qid:"):
            currentQID = int( currentLine.strip().split(":")[1].strip() )
            print "currentQID:",str( currentQID )
            if currentQID not in insideQueryIDAndResultSetDict:
                insideQueryIDAndResultSetDict[currentQID] = Set([])
            numOfQueriesHavingQID += 1
        
        # sample parsing line:
        # Search: u s  oil industry history
        if currentLine.startswith("Search:"):
            elementList = currentLine.strip().split(" ")
            
            currentSearchContent = ""
            
            queryTermList = []
            for element in elementList[1:]:
                if element.strip() != "":
                    queryTermList.append( element.strip() )        
            currentQueryLength = len(queryTermList)
            print "currentQueryLength:",currentQueryLength
    
            for element in queryTermList:
                currentSearchContent += element + " "
            
            print currentSearchContent
            numOfQueriesHavingSearchContent += 1
            
            
            currentQueryTermIndexDict = {}
            nextLine = inputFileHandler1.readline()
            #print nextLine.strip()
            if nextLine.strip() != "":
                # I think I can skip the line: 
                # [2013-05-24 14:20:44] 38871 terms with their lists length have been loaded.
                nextLine = inputFileHandler1.readline()
                nextLineElements = nextLine.strip().split(" ")
                # print "nextLineElements:",nextLineElements
                # sample parsing line: 
                # oil:0 industry:1 history:2 u:3 s:4
                for element in nextLineElements:
                    if element.split(":")[0] not in currentQueryTermIndexDict:
                        currentQueryTermIndexDict[ int(element.split(":")[1]) ] = element.split(":")[0]
                
                print "currentQueryTermIndexDict:",currentQueryTermIndexDict
                # print "len(currentQueryTermIndexDict):",len(currentQueryTermIndexDict)
                
                # Now, it is time to read the threshold line
                currentLine = inputFileHandler1.readline()
                if len(currentLine.strip().split(":")) == 2:
                    name = currentLine.strip().split(":")[0]
                    value = currentLine.strip().split(":")[1]
                    print name,"::",value
                else:
                    print "format problem"
                    exit(1)
                    
                # Now, it is time to read computation method line
                currentLine = inputFileHandler1.readline()
                if len(currentLine.strip().split(":")) == 2:
                    name = currentLine.strip().split(":")[0]
                    value = currentLine.strip().split(":")[1]
                    print name,"::",value
                else:
                    print "format problem"
                    exit(1)
                
                if numOfLinesStillNeededToSkip == 0:
                    # do nothing
                    pass
                elif numOfLinesStillNeededToSkip == 1:
                    # do nothing
                    currentLine = inputFileHandler1.readline()
                else:
                    # not yet consider the other situation
                    pass
                    
                # Now, it is time to read the actual training example line
                currentLine = inputFileHandler1.readline()
                numOfResultsForTheCurrentQuery = 0
                currentResultLines = []
                # print "len( currentLine.strip().split(" ") ):",len( currentLine.strip().split(" ") )
                # print "currentLine:",currentLine
                lineElements = currentLine.strip().split(" ")
                while len( lineElements ) == 35:
                    theRank = int(lineElements[0])
                    theDocID = lineElements[33]
                    if theRank <= 10:
                        insideQueryIDAndResultSetDict[currentQID].add( theDocID )
                    
                    numOfResultsForTheCurrentQuery += 1
                    currentResultLines.append(currentLine.strip())
                    currentLine = inputFileHandler1.readline()
                    lineElements = currentLine.strip().split(" ")
                   
                numOfResultsForTheAllQueries += numOfResultsForTheCurrentQuery
                
                # sampling method 1: among all the top10 documents, select those documents, open those documents and extract the corresponding postings.
                # This method make sure that once the document have been selected, ALL the coresponding postings will also be selected.
                # This sampling method has been developed on 2013/01/09
                
                print "numOfResultsForTheCurrentQuery:",numOfResultsForTheCurrentQuery
                print "len(currentResultLines):",len(currentResultLines)
                print
            
        currentLine = inputFileHandler1.readline()
        
    print "numOfQueriesHavingQID:",numOfQueriesHavingQID
    print "numOfQueriesHavingSearchContent:",numOfQueriesHavingSearchContent
    print "numOfQueriesHavingSearchResults:",numOfQueriesHavingSearchResults
    
    print "len(insideQueryIDAndResultSetDict):",len(insideQueryIDAndResultSetDict)
    
    return insideQueryIDAndResultSetDict
    '''
    for qid in insideQueryIDAndResultSetDict:
        if qid == "99956":
            for TOP10DocID in insideQueryIDAndResultSetDict[qid]:
                print TOP10DocID
    '''


print "main program begins..."
# options for input1:
# option1:
# inputFileName1 = "/home/diaosi/outputDirForResults/tail100Queries/ANDSemantics/TOP10000Results/TCP/results_TCP_1.0Kept_partialBM25"
# option2:
# inputFileName1 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP1000Results/GoldStandardResults/5KTop100ANDSemanticsRawResults"
# option3:
# inputFileName1 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP1000Results/GoldStandardResults/5KTop100ANDSemanticsResults_UNIVERSAL_1.0Kept_partialBM25"
# option4:
inputFileName1 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP1000Results/GoldStandardResults/5KTop100ANDSemanticsResults_UNIVERSAL_1.0Kept_probability_OUR_METHOD_Fake"
outsideQueryIDAndResultSetDict1 = getQueryIDAndResultSetGivenResultFile(inputFileName1,1)

# options for input2:
# option1:
# inputFileName2 = "/home/diaosi/outputDirForResults/tail100Queries/ANDSemantics/TOP10000Results/TCP-QV/results_TCP-QV_0.01Kept_partialBM25"
# option2:
# inputFileName2 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP100Results/results_TCP_0.01Kept_partialBM25"
# option3:
# inputFileName2 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP100Results/UNIVERSAL_BM25/results_UNIVERSAL_0.01Kept_partialBM25"
# option4:
# "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP1000Results/GoldStandardResults/5KTop100ANDSemanticsResults_UNIVERSAL_1.0Kept_probability_small_bug_backup_fixed"
# "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP100Results/UNIVERSAL_PROBABILITY/results_UNIVERSAL_0.9Kept_probability"
inputFileName2 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP100Results/UNIVERSAL_PROBABILITY_based_on_OUR_OWN_2D_probability/results_UNIVERSAL_0.01Kept_probability"
# inputFileName2 = "/home/diaosi/outputDirForResults/tail5KTestingQueries/ANDSemantics/TOP1000Results/GoldStandardResults/5KTop100ANDSemanticsResults_UNIVERSAL_1.0Kept_partialBM25"
outsideQueryIDAndResultSetDict2 = getQueryIDAndResultSetGivenResultFile(inputFileName2,1)

# Now the results should be the same
queryIDList = outsideQueryIDAndResultSetDict1.keys()
queryIDList.sort()

# temp NOT used currently
# allQueriesIntersectionSet = Set([])
# allQueriesUnionSet = Set([])

all_queries_average_symmetric_difference_value = 0.0
num_valid_queries = 0

for queryID in queryIDList:
    if queryID in outsideQueryIDAndResultSetDict1 and queryID in outsideQueryIDAndResultSetDict2:
        intersectionSet = outsideQueryIDAndResultSetDict1[queryID].intersection( outsideQueryIDAndResultSetDict2[queryID] )
        unionSet = outsideQueryIDAndResultSetDict1[queryID].union( outsideQueryIDAndResultSetDict2[queryID] )
        
        symmetric_difference_value = 0.0
        
        if len(unionSet) == 0:
            print "queryID:",str(queryID),"symmetric_difference:","N/A cause there are NO results"
        else:
            symmetric_difference_value = len(intersectionSet)/len(unionSet)
            all_queries_average_symmetric_difference_value += symmetric_difference_value
            num_valid_queries += 1
            print "queryID:",str(queryID),"symmetric_difference:",symmetric_difference_value
            
            # Just for checking
            '''
            if symmetric_difference_value != 1.0:
                print "has problem with the queryID:",queryID,symmetric_difference_value
                exit(1)
            '''
        
        '''
        if queryID in outsideQueryIDAndResultSetDict2:
            pass
        else:
            print "error"
            exit(1)
        '''

print "num_valid_queries:",num_valid_queries
print "all_queries_average_symmetric_difference_value:",all_queries_average_symmetric_difference_value/num_valid_queries
print "pass"
print "main program ends."

















